/******************************************************************************************/
/**** FILE: hot_color.cpp                                                              ****/
/******************************************************************************************/

#include <stdlib.h>
#include <math.h>
#include "hot_color.h"

/******************************************************************************************/
/**** FUNCTION: HotColorClass::HotColorClass                                           ****/
/******************************************************************************************/
HotColorClass::HotColorClass()
{
    max_num_color = 12;
    color_list = (int **) malloc(max_num_color*sizeof(int *));

    int i;
    for (i=0; i<=max_num_color-1; i++) {
        color_list[i] = (int  *) malloc((i+1)*sizeof(int  ));
    }

    int ratio=2;
    /**************************************************************************************/
    /**** num_color = 1                                                                ****/
    /**************************************************************************************/
    color_list[0][0] = 16711680;
    /**************************************************************************************/

    /**************************************************************************************/
    /**** num_color = 2                                                                ****/
    /**************************************************************************************/
    color_list[1][0] = 255;
    color_list[1][1] = 16711680;
    /**************************************************************************************/

    /**************************************************************************************/
    /**** num_color = 3                                                                ****/
    /**************************************************************************************/
    color_list[2][0] = 255;
    color_list[2][1] = 65280;
    color_list[2][2] = 16711680;
    /**************************************************************************************/

    /**************************************************************************************/
    /**** num_color = 4                                                                ****/
    /**************************************************************************************/
    color_list[3][0] = 255;
    color_list[3][1] = 65280;
    color_list[3][2] = 16776960;
    color_list[3][3] = 16711680;
    /**************************************************************************************/

    /**************************************************************************************/
    /**** num_color = 5                                                                ****/
    /**************************************************************************************/
    color_list[4][0] = 255;
    color_list[4][1] = 65535;
    color_list[4][2] = 65280;
    color_list[4][3] = 16776960;
    color_list[4][4] = 16711680;
    /**************************************************************************************/

    /**************************************************************************************/
    /**** num_color = 6                                                                ****/
    /**************************************************************************************/
    color_list[5][0] = 255;
    color_list[5][1] = 65535;
    color_list[5][2] = 65280;
    color_list[5][3] = 16776960;
    color_list[5][4] = 16711680;
    color_list[5][5] = 16711935;
    /**************************************************************************************/

    /**************************************************************************************/
    /**** num_color = 7                                                                ****/
    /**************************************************************************************/
    color_list[6][0] = 255;
    color_list[6][1] = 65535;
    color_list[6][2] = 65280;
    color_list[6][3] = 16776960;
    color_list[6][4] = 16744192;
    color_list[6][5] = 16711680;
    color_list[6][6] = 16711935;
    /**************************************************************************************/

    /**************************************************************************************/
    /**** num_color = 8                                                                ****/
    /**************************************************************************************/
    color_list[7][0] = 191;
    color_list[7][1] = 32767;
    color_list[7][2] = 65535;
    color_list[7][3] = 32575;
    color_list[7][4] = 65280;
    color_list[7][5] = 16776960;
    color_list[7][6] = 12541696;
    color_list[7][7] = 16711680;
    /**************************************************************************************/

    /**************************************************************************************/
    /**** num_color = 9                                                                ****/
    /**************************************************************************************/
    color_list[8][0] = 191;
    color_list[8][1] = 32767;
    color_list[8][2] = 65535;
    color_list[8][3] = 32575;
    color_list[8][4] = 48896;
    color_list[8][5] = 8388352;
    color_list[8][6] = 16776960;
    color_list[8][7] = 12541696;
    color_list[8][8] = 16711680;
    /**************************************************************************************/

    /**************************************************************************************/
    /**** num_color = 10                                                               ****/
    /**************************************************************************************/
    color_list[9][0] = 191;
    color_list[9][1] = 32767;
    color_list[9][2] = 65535;
    color_list[9][3] = 32575;
    color_list[9][4] = 48896;
    color_list[9][5] = 8388352;
    color_list[9][6] = 16776960;
    color_list[9][7] = 8339200;
    color_list[9][8] = 12517376;
    color_list[9][9] = 16711807;
    /**************************************************************************************/

    /**************************************************************************************/
    /**** num_color = 11                                                               ****/
    /**************************************************************************************/
    color_list[10][0] = 191;
    color_list[10][1] = 32767;
    color_list[10][2] = 65535;
    color_list[10][3] = 32575;
    color_list[10][4] = 48896;
    color_list[10][5] = 8388352;
    color_list[10][6] = 16776960;
    color_list[10][7] = 8339200;
    color_list[10][8] = 12517376;
    color_list[10][9] = 16711807;
    color_list[10][10] = 16711935;
    /**************************************************************************************/

    /**************************************************************************************/
    /**** num_color = 12                                                               ****/
    /**************************************************************************************/
    color_list[11][0] = 4128895;
    color_list[11][1] = 191;
    color_list[11][2] = 32767;
    color_list[11][3] = 65535;
    color_list[11][4] = 32575;
    color_list[11][5] = 48896;
    color_list[11][6] = 8388352;
    color_list[11][7] = 16776960;
    color_list[11][8] = 8339200;
    color_list[11][9] = 12517376;
    color_list[11][10] = 16711807;
    color_list[11][11] = 16711935;
    /**************************************************************************************/
}
/******************************************************************************************/
/**** FUNCTION: HotColorClass::~HotColorClass                                          ****/
/******************************************************************************************/
HotColorClass::~HotColorClass()
{
    int i;

    for (i=0; i<=max_num_color-1; i++) {
        free(color_list[i]);
    }
    free(color_list);
}
/******************************************************************************************/
/**** FUNCTION: HotColorClass::get_color()                                             ****/
/******************************************************************************************/
int HotColorClass::get_color(int i, int n)
{
    int color;

    if (n < 1) {
        color = 0;
    } else {
        if (n > max_num_color) {
            n = max_num_color;
        }
        if ( (i < 0) ) {
            color = 0;
        } else {
            color = color_list[n-1][i % n];
        }
    }

    return(color);
}
/******************************************************************************************/
/**** FUNCTION: HotColorClass::get_color()                                             ****/
/******************************************************************************************/
int HotColorClass::get_color(int i)
{
    int color = get_color(i, max_num_color);
    return(color);
}

/******************************************************************************************/
// - 190630 Chengan
// fomula see : 
//         https://www.particleincell.com/2014/colormap/
//         https://stackoverflow.com/questions/7706339/grayscale-to-red-green-blue-matlab-jet-color-scale
// color factor f from 0 to 1, color from cold -> hot , blue -> red
/******************************************************************************************/
QColor HotColorClass::cal_color(double f)
{
    QColor color = cal_color_value(f);

    return color;
}
int HotColorClass::cal_color_value(double f)
{
    /*plot short rainbow RGB*/
    int r,g,b;
    double a = (1-f)/0.25;             //invert and group
    int    x = floor(a);               //this is the integer part
    double y = floor(255*(a-x));       //fractional part from 0 to 255
    switch(x) {
      case 0 : r=255;   g=y;     b=0;   break;
      case 1 : r=255-y; g=255;   b=0;   break;
      case 2 : r=0;     g=255;   b=y;   break;
      case 3 : r=0;     g=255-y; b=255; break;
      case 4 : r=0;     g=0;     b=255; break;
    }
    int v = ((r*256)+g)*256+b;

    //printf("f %f RGB(%d,%d,%d) value %d \n",f,r,g,b,v);

    return v;
}
// input i, index of color
QColor HotColorClass::cal_color(int i,int num)
{
    QColor color = cal_color_value(i,num);

    return color;
}
// factor f = i/(number of color level-1)
int HotColorClass::cal_color_value(int i,int num)
{

    //plot short rainbow RGB
    // from red->blue
    double f = (double)i/(num-1);

    // from red->green, only half of colors
    // f[0.5,1] i[0,num-1] green -> red
    //double f = (double)i/(2*(num-1))+0.5;

    int r,g,b;
    double a = (1-f)/0.25;             //invert and group
    int    x = floor(a);               //this is the integer part
    double y = floor(255*(a-x));       //fractional part from 0 to 255
    switch(x) {
      case 0 : r=255;   g=y;     b=0;   break;
      case 1 : r=255-y; g=255;   b=0;   break;
      case 2 : r=0;     g=255;   b=y;   break;
      case 3 : r=0;     g=255-y; b=255; break;
      case 4 : r=0;     g=0;     b=255; break;
    }

    return ((r*256)+g)*256+b;
}
/******************************************************************************************/
